import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLConnection;
import java.util.Map;

import javax.swing.JOptionPane;

import com.speljohan.rsbot.event.events.ServerMessageEvent;
import com.speljohan.rsbot.event.listeners.PaintListener;
import com.speljohan.rsbot.event.listeners.ServerMessageListener;
import com.speljohan.rsbot.script.Calculations;
import com.speljohan.rsbot.script.Constants;
import com.speljohan.rsbot.script.GEItemInfo;
import com.speljohan.rsbot.script.Script;
import com.speljohan.rsbot.script.wrappers.RSInterface;
import com.speljohan.rsbot.script.wrappers.RSNPC;
import com.speljohan.rsbot.script.wrappers.RSObject;
import com.speljohan.rsbot.script.wrappers.RSTile;

public class FlaxPicker extends Script implements PaintListener,
		ServerMessageListener {

	int flaxPicked;
	int flaxpick = 0;
	int trips = 0;
	final static int WELCOME_ID = 378;
	public int Flax = 2646;
	public int BankBooth = 25808;
	public int FlaxItem = 1779;
	public int[] Ladder = { 25938, 25939 };
	public int bowstringItem = 1777;
	public int[] NPCBanker = { 2354, 2355 };
	private int flaxPrice = 0;
	private int bowstringPrice = 0;
	private long Time = 0;
	private boolean AntiBan;
	private boolean NPCBanking;
	public String noBan;
	public String flaxLocation;
	private String state = "Starting up...";
	private String location = "";
	private String Location = "";

	// End
	public RSTile[] flaxToBank;
	public RSTile[] bankToFlax;

	public RSTile[] walkBack = new RSTile[] { new RSTile(2755, 3401),
			new RSTile(2753, 3413), new RSTile(2752, 3426),
			new RSTile(2739, 3428), new RSTile(2740, 3443) };

	private int antiBan() {
		final int randomA = random(1, 3);
		if (randomA == 1) {
			setCameraRotation(random(0, 60));
		}
		if (randomA == 2) {
			if (getCurrentTab() != Constants.TAB_INVENTORY) {
				openTab(Constants.TAB_INVENTORY);
			}
			setCameraRotation(random(0, 60));
		}
		if (randomA == 3) {
			setCameraAltitude(true);
		}
		return -1;
	}

	public boolean Arandom() {
		if (AntiBan == true) {
			if (AntiBan == !true) {
				return false;
			}
		}
		if (random(0, 5) == 1) {
			antiBan();
		}
		return true;

	}

	public boolean atWelcomeScreen() {
		if (RSInterface.getInterface(FlaxPicker.WELCOME_ID).isValid()
				&& !RSInterface.getInterface(FlaxPicker.WELCOME_ID)
						.getChild(89).getText().contains("10.1120.190")) {
			;
			log("Clicking play...");
			clickMouse(381, 430, true);
			return true;
		}
		return false;
	}

	public boolean banED() {
		if (AntiBan == true) {
			log("Anti-Ban Enabled!");
		}
		if (AntiBan == false) {
			log("Anti-Ban Disabled!");
		}
		return true;
	}

	public boolean bankToFlax() {
		state = "Walking to flax...";
		Location = "" + location;
		final RSTile[] randomizedPath = randomizePath(bankToFlax, 2, 2);
		return walkPathMM(randomizedPath, 15);
	}

	private boolean clickTile(final RSTile tile, final String option) {
		try {
			final Point location = Calculations.tileToScreen(tile);
			if (location.x == -1 || location.y == -1) {
				return false;
			}
			moveMouse(location);
			atMenu(option);
			return true;
		} catch (final Exception e) {
			return false;
		}
	}

	public boolean donePicking() {
		if (flaxpick > 0) {
			return false;
		}
		if (flaxpick == 0) {
			log("Done picking flax...");
		}
		log("Logging out...");
		logout();
		log("Stopping all scripts...");
		stopAllScripts();
		return true;
	}

	public boolean fieldToBank() {
		state = "Walking to bank...";
		Location = "" + location;
		final RSTile[] randomizedPath = randomizePath(flaxToBank, 2, 2);
		return walkPathMM(randomizedPath, 15);
	}

	public String getAuthor() {
		return "TheShadow";
	}

	// MouseSpeed
	/*
	 * This sets the mouse speed, lower numbers means faster mouse speed, and
	 * higher numbers mean slower mouse speed.
	 */
	@Override
	protected int getMouseSpeed() {
		return 7; // This is the NUMBER you change to change the speed
	}

	public String getName() {
		return "TheShadow's Flax Picker";
	}

	public String getScriptCategory() {
		return "Crafting";
	}

	public String getScriptDescription() {
		String html = "";

		html += "<html>\n";
		html += "<body>\n";
		html += "<h2>" + getName() + " v" + getVersion() + "</h2><br>\n";
		html += "Start in bank or flax field of your desired location.<br><br>";
		html += "<tr><td><b>Location: </b></td><td><center><select name=\"flaxLocation\">";
		html += "<option>Seers";
		html += "<option>Lletya";
		html += "</select></center></td></tr>";
		html += "How much flax would you like to pick?<br><br>";
		html += "<input type=\"text\" name=\"pickamount\" value=\"1000\"><br>";
		html += "<tr><td><b>Enable built in Anti-Ban?: </b></td><td><input type=\"checkbox\" name=\"noBan\" checked=\"true\" value=\"true\"><B>Yes</b></td></tr>";
		html += "<br>";
		html += "</body>\n";
		html += "</html\n";

		return html;
	}

	public double getVersion() {
		return 3.40;
	}

	public boolean goDown() {
		state = "Going down ladder...";
		final RSObject ladder = getNearestObjectByID(Ladder);
		if (ladder == null) {
			return false;
		}

		return atObject(ladder, "own");
	}

	public int loop() {
		if (getEnergy() >= random(75, 99) && !isRunning()) {
			setRun(isActive);
		}
		if (random(0, 2) == 1) {
			Arandom();
		}

		if (atWelcomeScreen()) {
			return random(800, 1000);
		} else {
			if (donePicking()) {
				return random(800, 1000);
			} else

			if (upBank()) {
				if (goDown()) {
					return random(800, 1000);
				}

			} else {
				if (needToBank()) {

					if (nearBank()) {
						if (useBank()) {
							return random(800, 1000);
						}

					} else {
						if (fieldToBank()) {
							return random(800, 1000);
						}
					}

				} else {
					if (nearFlax()) {
						if (pickFlax()) {
							return random(200, 400);
						}
					} else {
						if (bankToFlax()) {
							if (WalkBack()) {
								return random(800, 1000);
							}
						}
					}
				}
			}
			return random(800, 1000);
		}
	}

	public boolean nearBank() {
		if (NPCBanking == true) {
			final RSNPC banker = getNearestNPCByID(NPCBanker);
			if (banker == null) {
				return false;
			}

			return tileOnScreen(banker.getLocation());
		}

		if (NPCBanking == false) {
			final RSObject bankBooth = getNearestObjectByID(BankBooth);
			if (bankBooth == null) {
				return false;
			}

			return tileOnScreen(bankBooth.getLocation());
		}
		return true;
	}

	public boolean nearFlax() {
		final RSObject flax = getNearestObjectByID(Flax);
		if (flax == null) {
			return false;
		}

		return tileOnScreen(flax.getLocation());
	}

	public boolean needToBank() {
		return isInventoryFull();
	}

	public void onFinish() {
		long millis = System.currentTimeMillis() - Time;
		final long hours = millis / (1000 * 60 * 60);
		millis -= hours * 1000 * 60 * 60;
		final long minutes = millis / (1000 * 60);
		millis -= minutes * 1000 * 60;
		final long seconds = millis / 1000;
		toggleRandom("Welcome Screen", true);
		log("Reporting data...");
		log("Flax Picked: " + flaxPicked);
		log("Trips: " + trips);
		log("Money Earned From Picking Flax: " + flaxPicked * flaxPrice + " GP");
		log("Money Earned if Spun Into Bowstring: " + flaxPicked
				* bowstringPrice + " GP");
		log("Total Time Ran: Hours: " + hours + " Minutes: " + minutes
				+ " Seconds: " + seconds);
		return;
	}

	@Override
	public void onRepaint(final Graphics render) {
		long millis = System.currentTimeMillis() - Time;
		final long hours = millis / (1000 * 60 * 60);
		millis -= hours * 1000 * 60 * 60;
		final long minutes = millis / (1000 * 60);
		millis -= minutes * 1000 * 60;
		final long seconds = millis / 1000;
		final int x = 538;
		final int y = 15;
		final int mx = 226;
		final int my = 357;
		if (isLoggedIn()) {
			render.setColor(new Color(0, 0, 0, 175));
			render.fillRoundRect(521, 3, 245, 164, 10, 10);
			render.setColor(Color.WHITE);
			render
					.drawString("TheShadow's Flax Picker V " + getVersion(), x,
							y);
			final String str = "Flax Picked: " + Integer.toString(flaxPicked);
			final String str7 = "Trips: " + Integer.toString(trips);
			final String str4 = "Amount of flax to pick: "
					+ Integer.toString(flaxpick);
			final String str5 = "Status: " + state;
			final String str6 = "Location: " + Location;
			render.drawString(str, x, y + 15);
			render.drawString(str7, x, y + 30);
			render.drawString(str4, x, y + 45);
			render.drawString(str5, x, y + 90);
			render.drawString(str6, x, y + 60);
			render.drawString("Time Running: " + hours + ":" + minutes + ":"
					+ seconds, x, y + 75);
			render.setColor(new Color(0, 0, 0, 175));
			render.fillRoundRect(222, 346, 275, 30, 10, 10);
			render.setColor(Color.GREEN);
			final String str2 = "Money earned from picking Flax: "
					+ Integer.toString(flaxPicked * flaxPrice);
			final String str3 = "Money made if spun into Bow Strings: "
					+ Integer.toString(flaxPicked * bowstringPrice);
			render.drawString(str2, mx, my);
			render.drawString(str3, mx, my + 15);
		}

	}

	public boolean onStart(final Map<String, String> args) {
		// Credits to 0x098b4a40 for base script
		URLConnection url = null;
		BufferedReader in = null;
		final BufferedWriter out = null;
		if (JOptionPane.showConfirmDialog(null,
				"Would you like to check for updates?") == 0) {
			try {
				url = new URL(
						"http://lotwow.webs.com/scripts/FlaxPickerVERSION.txt")
						.openConnection();
				in = new BufferedReader(new InputStreamReader(url
						.getInputStream()));
				if (Double.parseDouble(in.readLine()) > getVersion()) {
					final int update = JOptionPane.showConfirmDialog(null,
							"Update found. Do you wish to update?", "Update",
							JOptionPane.YES_NO_OPTION);
					if (update == 0) {
						openURL("http://www.rsbot.org/vb/showthread.php?t=29705");
					}
					final int change = JOptionPane.showConfirmDialog(null,
							"Would you like to view the change log?",
							"Change Log", JOptionPane.YES_NO_OPTION);
					if (change == 0) {
						openURL("http://lotwow.webs.com/scripts/FlaxPickerChange.html");
					}
					log("Copy and paste the code from the post to update and re-compile.");
					return false;
				} else {
					JOptionPane.showMessageDialog(null,
							"You have the latest version.");
				}

				if (in != null) {
					in.close();
				}
				if (out != null) {
					out.close();
				}
			} catch (final IOException e) {
				log("Problem getting version!  This may happen if im adding a new version.");
				log("Please wait 1-5 minutes.");
				return false;
			}
		}// END
		final int ads = JOptionPane.showConfirmDialog(null,
				"Would you like to support me by clicking a advertisement?",
				"Starting Up", JOptionPane.YES_NO_OPTION);
		if (ads == 0) {
			final String message = "<html><b>Thank you for your support!</b><br/>"
					+ "<p>You will be redirected to the advertise page to click an ad.<br/>"
					+ "Please try and click the ad a couple a times a day.</p>"
					+ "</html>";
			JOptionPane.showMessageDialog(null, message);
			openURL("http://rsbotd.10001mb.com/");
		}
		Time = System.currentTimeMillis();
		toggleRandom("Welcome Screen", false);
		flaxpick = Integer.parseInt(args.get("pickamount"));
		AntiBan = args.get("noBan") != null ? true : false;
		flaxLocation = args.get("flaxLocation");
		if (banED()) {
			;
		}
		if (flaxLocation.equals("Seers")) {
			log("Setting script for Seers...");
			location = "Seers";
			flaxToBank = new RSTile[] { new RSTile(2732, 3442),
					new RSTile(2728, 3452), new RSTile(2727, 3463),
					new RSTile(2726, 3477), new RSTile(2725, 3491) };
			bankToFlax = new RSTile[] { new RSTile(2725, 3485),
					new RSTile(2722, 3472), new RSTile(2726, 3460),
					new RSTile(2731, 3450), new RSTile(2733, 3445),
					new RSTile(2739, 3444) };
			NPCBanking = false;
		}
		if (flaxLocation.equals("Lletya")) {
			location = "Lletya";
			log("Setting script for Lletya...");
			flaxToBank = new RSTile[] { new RSTile(2352, 3162) };
			bankToFlax = new RSTile[] { new RSTile(2356, 3153) };
			NPCBanking = true;
		}
		log("Getting price for Flax");
		final GEItemInfo flax = grandExchange.loadItemInfo(FlaxItem);
		flaxPrice = flax.getMarketPrice();
		log("Getting price for Bow Strings");
		final GEItemInfo bowstring = grandExchange.loadItemInfo(bowstringItem);
		bowstringPrice = bowstring.getMarketPrice();
		log("Prices retreived from Grand Exchange, Showing Market Price");
		log("Flax Market Price = " + flaxPrice + " GP");
		log("Bow String Market Price = " + bowstringPrice + " GP");
		log("Amount of flax to pick: " + flaxpick);
		log("Finished starting up....Running Main Script(TheShadow's Flax Picker)");

		return true;
	}

	@SuppressWarnings("unchecked")
	public void openURL(final String url) {
		final String osName = System.getProperty("os.name");
		try {
			if (osName.startsWith("Mac OS")) {
				final Class fileMgr = Class
						.forName("com.apple.eio.FileManager");
				final Method openURL = fileMgr.getDeclaredMethod("openURL",
						new Class[] { String.class });
				openURL.invoke(null, new Object[] { url });
			} else if (osName.startsWith("Windows")) {
				Runtime.getRuntime().exec(
						"rundll32 url.dll,FileProtocolHandler " + url);
			} else {
				final String[] browsers = { "firefox", "opera", "konqueror",
						"epiphany", "mozilla", "netscape" };
				String browser = null;
				for (int count = 0; count < browsers.length && browser == null; count++) {
					if (Runtime.getRuntime().exec(
							new String[] { "which", browsers[count] })
							.waitFor() == 0) {
						browser = browsers[count];
					}
				}
				if (browser == null) {
					throw new Exception("Could not find web browser");
				} else {
					Runtime.getRuntime().exec(new String[] { browser, url });
				}
			}
		} catch (final Exception e) {
		}
	}

	public boolean pickFlax() {
		state = "Picking flax...";
		Location = "" + location + " - Flax Fields";

		final RSObject flax = getNearestObjectByID(Flax);
		final RSTile flaxTile = flax.getLocation();

		if (!getMyPlayer().isMoving()) {
			clickTile(flaxTile, "Pick");
		}
		return true;
	}

	@Override
	public void serverMessageRecieved(final ServerMessageEvent e) {
		final String message = e.getMessage();
		if (message.contains("You pick some flax")) {
			flaxPicked++;
			flaxpick--;
		}

	}

	public void setRun(final boolean enable) {
		if (isRunning() == enable) {
			return;
		}
		atInterface(750, 0);
	}

	public boolean upBank() {
		if (getPlane() == 1) {
			return true;
		}
		return false;
	}

	public boolean useBank() {
		state = "Banking...";
		Location = "" + location + " - Bank";

		if (NPCBanking == true) {
			final RSNPC Banker = getNearestNPCByID(NPCBanker);
			final RSTile bankerTile = Banker.getLocation();
			if (Banker == null) {
				return false;
			}

			if (bank.isOpen()) {
				bank.depositAll();
				trips++;
			} else {
				if (!getMyPlayer().isMoving()) {
					clickTile(bankerTile, "Bank Banker");
				}
			}
		}
		if (NPCBanking == false) {
			final RSObject bankBooth = getNearestObjectByID(BankBooth);
			final RSTile booth = bankBooth.getLocation();

			if (bankBooth == null) {
				return false;
			}

			if (bank.isOpen()) {
				bank.depositAll();
				trips++;
			} else {
				if (!getMyPlayer().isMoving()) {
					clickTile(booth, "uickly");
				}
			}
		}
		return true;
	}

	public boolean WalkBack() {
		state = "Walking back to flax...";
		final RSTile[] randomizedPath = randomizePath(walkBack, 2, 2);
		return walkPathMM(randomizedPath, 15);
	}
}